package org.soderiakelvy.model.service.imp;

import java.io.Serializable;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.soderiakelvy.controller.util.Util;
import org.soderiakelvy.model.dao.ComercializacionMesVencidoDao;
import org.soderiakelvy.model.dao.ComercializacionPackDao;
import org.soderiakelvy.model.dao.FrioCalorDao;
import org.soderiakelvy.model.dao.SucursalDao;
import org.soderiakelvy.model.dao.SucursalFrioCalorDao;
import org.soderiakelvy.model.dao.SucursalPackDao;
import org.soderiakelvy.model.dao.SucursalProductoDao;
import org.soderiakelvy.model.dao.VisitaDao;
import org.soderiakelvy.model.dao.imp.ComercializacionMesVencidoDaoImp;
import org.soderiakelvy.model.dao.imp.ComercializacionPackDaoImp;
import org.soderiakelvy.model.dao.imp.FrioCalorDaoImp;
import org.soderiakelvy.model.dao.imp.SucursalDaoImp;
import org.soderiakelvy.model.dao.imp.SucursalFrioCalorDaoImp;
import org.soderiakelvy.model.dao.imp.SucursalPackDaoImp;
import org.soderiakelvy.model.dao.imp.SucursalProductoDaoImp;
import org.soderiakelvy.model.dao.imp.VisitaDaoImp;
import org.soderiakelvy.model.domain.ComercializacionMesVencidoVO;
import org.soderiakelvy.model.domain.ComercializacionPackVO;
import org.soderiakelvy.model.domain.DesProdTipoCliVO;
import org.soderiakelvy.model.domain.FrioCalorVO;
import org.soderiakelvy.model.domain.ProductoVO;
import org.soderiakelvy.model.domain.SucursalFrioCalorVO;
import org.soderiakelvy.model.domain.SucursalPackVO;
import org.soderiakelvy.model.domain.SucursalProductoVO;
import org.soderiakelvy.model.domain.SucursalVO;
import org.soderiakelvy.model.domain.SujetoVO;
import org.soderiakelvy.model.domain.VisitaVO;
import org.soderiakelvy.model.service.SucursalServicio;
import org.soderiakelvy.model.util.ConstantModel;


public class SucursalServicioImp implements SucursalServicio,Serializable{
	private static final long serialVersionUID = 1L;
	//--- ATRIBUTOS ---
    private SucursalDao sucursalDao;
    private VisitaDao visitaDao;
    private SucursalProductoDao sucursalProductoDao; 
    private SucursalPackDao sucursalPackDao;
    private SucursalFrioCalorDao sucursalFrioCalorDao;
    private ComercializacionMesVencidoDao comercializacionMesVencidoDao;
    private ComercializacionPackDao comercializacionPackDao;

    //--- CONSTRUCTOR ---
    public SucursalServicioImp(){
        sucursalDao = new SucursalDaoImp();
        visitaDao = new VisitaDaoImp();
        sucursalProductoDao = new SucursalProductoDaoImp();
        sucursalPackDao = new SucursalPackDaoImp();
        sucursalFrioCalorDao = new SucursalFrioCalorDaoImp();
        comercializacionMesVencidoDao = new ComercializacionMesVencidoDaoImp();
        comercializacionPackDao = new ComercializacionPackDaoImp();
    }

	@Override
	public String insertSucursal(SucursalVO sucursal) {
		sucursal.setNombre(sucursal.getNombre().trim().toUpperCase());
		sucursal.setApellido(sucursal.getApellido().trim().toUpperCase());
		sucursal.setFechaAlta(new Date());
		try {
			sucursalDao.insertSucursalVO(sucursal);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al insertar una sucursal. "+e.getMessage());
			return ConstantModel.FAILED;
		}
		
	}
	
	@Override
	public Boolean existeNombreSucursal(String nombre) {
		try{
			if (sucursalDao.getSucursalByNombre(nombre) != null){
				return true;
			}else
				return false;
		}catch (Exception e){
			e.printStackTrace();
			System.out.println("Error al buscar nombre de Sucursal. "+e.getMessage());
			return null;	
		}
	}

	@Override
	public String updateSucursal(SucursalVO sucursal) {
		try {
			sucursalDao.updateSucursalVO(sucursal);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al actualizar una sucursal. "+e.getMessage());
			return ConstantModel.FAILED;
		}
		
	}

	@Override
	public String deleteSucursal(SucursalVO sucursal) {
		try {
			sucursalDao.deleteSucursalVO(sucursal);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al eliminar una sucursal. "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public SucursalVO getSucursalVO(SucursalVO sucursal) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<SucursalVO> getSucursalesFromSujeto(SujetoVO sujeto) {
		try {
			List<SucursalVO> sucursales = sucursalDao.getSucursalesFromSujeto(sujeto);
			for(SucursalVO s : sucursales){
				s.setDomicilioCompleto(Util.getDireccion(s));
			}
			return sucursales;	
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al listar las sucursales de un sujeto. "+e.getMessage());
			return null;
		}
	}

	@Override
	public List<SucursalProductoVO> getProductosPorSucursal(SucursalVO sucursal) {
		List<SucursalProductoVO> result = new ArrayList<SucursalProductoVO>();
		try {
			result = sucursalProductoDao.getAllSucursalProductoBySucursal(sucursal);
			for(SucursalProductoVO sp: result){
				float precioReal = sp.getProductoDescuento().getProducto().getPrecio() - (sp.getProductoDescuento().getProducto().getPrecio() * sp.getProductoDescuento().getPorcentajeDescuento() / 100);
				sp.getProductoDescuento().getProducto().setPrecio(precioReal);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			result = null;
		}
		return result;
	}

	@Override
	public int getUltimoNumeroSucursal(SujetoVO sujeto) {
        int numeroMaximo = 0;
        for(SucursalVO s: getSucursalesFromSujeto(sujeto)){
            if(s.getNumeroSucursal()>numeroMaximo)
                numeroMaximo = s.getNumeroSucursal();
        }
        return numeroMaximo + 1;
	}

	@Override
	public void insertVisitaVO(SucursalVO sucursal, String[]dias) {
		VisitaVO visita = new VisitaVO();
		for (int i = 0; i < dias.length; i++) {
			if(dias[i].equals("1"))
				visita.setLunes((short)1);
			if(dias[i].equals("2"))
				visita.setMartes((short)1);
			if(dias[i].equals("3"))
				visita.setMiercoles((short)1);
			if(dias[i].equals("4"))
				visita.setJueves((short)1);
			if(dias[i].equals("5"))
				visita.setViernes((short)1);
			if(dias[i].equals("6"))
				visita.setSabado((short)1);
		}
		visita.setSucursal(sucursal);
		try {
			visitaDao.insertVisitaVO(visita);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al guardar una visita");
		}
	}

	@Override
	public String insertSucursalPrincipal(SucursalVO sucursal, SujetoVO sujeto) {
		return ConstantModel.FAILED;
	}


	//---------------------METODOS DE SUCURSAL-PRODUCTO---------------------------------
	
	@Override
	public String insertSucursalProductoVO(SucursalProductoVO sucursalProducto) {
		try{
			sucursalProductoDao.insertSucursalProductoVO(sucursalProducto);
			return ConstantModel.SUCCESS;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al guardar un Sucrusal-Producto "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String updateSucursalProductoVO(SucursalProductoVO sucursalProducto) {
		try{
			sucursalProductoDao.updateSucursalProductoVO(sucursalProducto);
			return ConstantModel.SUCCESS;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al Actualizar un SucursalProducto "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String deleteSucursalProductoVO(SucursalProductoVO sucursalProducto) {
		try{
			sucursalProductoDao.deleteSucursalProductoVO(sucursalProducto);
			return ConstantModel.SUCCESS;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al Eliminar un SucursalProducto "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public SucursalProductoVO getSucursalProductoById(long sucursalProductoId) {
		try{
			return sucursalProductoDao.getSucursalProductoVOById(sucursalProductoId);
		}catch (Exception e){
			e.printStackTrace();
			System.out.println("Error al Obtener un Sucursal-Producto "+ e.getMessage());
			return null;			
		}
	}
	
	@Override
	public List<SucursalProductoVO> getSucursalesProductos() {
		try {
			return sucursalProductoDao.getAllSucursalProductoVO();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al listar Sucursales-producto "+e.getMessage());
			return null;
		}
	}
	
	@Override
	public List<SucursalProductoVO> getSucursalProductoBySucursal(SucursalVO sucursal) {
		try {
			return sucursalProductoDao.getAllSucursalProductoBySucursal(sucursal);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al listar Sucursales-producto por sucursal"+e.getMessage());
			return null;
		}
	}
	
	//----------------------------------------------------------------------------------

	@Override
	public String insertComercializacionMesVencidoVO(
			ComercializacionMesVencidoVO comercializacionMesVencido) {
		comercializacionMesVencido.setFechaAsignacion(new Date());
		try {
			comercializacionMesVencidoDao.insertComercializacionMesVencidoVO(comercializacionMesVencido);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String updateComercializacionMesVencidoVO(
			ComercializacionMesVencidoVO comercializacionMesVencido) {
		try {
			comercializacionMesVencidoDao.updateComercializacionMesVencidoVO(comercializacionMesVencido);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String deleteComercializacionMesVencidoVO(
			ComercializacionMesVencidoVO comercializacionMesVencido) {
		try {
			comercializacionMesVencidoDao.deleteComercializacionMesVencidoVO(comercializacionMesVencido);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return ConstantModel.FAILED;
		}
	}

	//--------- COMERCIALIZACION PACK SERVICES --------
	@Override
	public String insertComercializcionPackVO(
			ComercializacionPackVO comercializacionPack) {
		try {			
			comercializacionPackDao.insertComercializacionPackVO(comercializacionPack);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String updateComercializcionPackVO(
			ComercializacionPackVO comercializacionPack) {
		try {
			comercializacionPackDao.updateComercializacionPackVO(comercializacionPack);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String deleteComercializcionPackVO(ComercializacionPackVO comercializacionPack) {
		try {
			comercializacionPackDao.deleteComercializacionPackVO(comercializacionPack);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			return ConstantModel.FAILED;
		}
	}

	@Override
	public List<ComercializacionPackVO> getComercializacionesPackBySucursal(SucursalVO sucursal) {
		try {
			return comercializacionPackDao.getComercializacionBySucursal(sucursal);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	//-----------	METODOS PARA SUCURSAL-PACK----------------------------
	@Override
	public String insertSucursalPackVO(SucursalPackVO sucursalPack) {
		try{
			sucursalPackDao.insertSucursalPackVO(sucursalPack);
			return ConstantModel.SUCCESS;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al guardar un Sucrusal-Pack "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String updateSucursalPackVO(SucursalPackVO sucursalPack) {
		try{
			sucursalPackDao.updateSucursalPackVO(sucursalPack);
			return ConstantModel.SUCCESS;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al Actualizar un SucursalPack "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String deleteSucursalPackVO(SucursalPackVO sucursalPack) {
		try{
			sucursalPackDao.deleteSucursalPackVO(sucursalPack);
			return ConstantModel.SUCCESS;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al Eliminar un SucursalPack "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public SucursalPackVO getSucursalPackById(long sucursalPackId) {
		return null;
	}

	@Override
	public List<SucursalPackVO> getSucursalesPacks() {
		try {
			return sucursalPackDao.getAllSucursalPackVO();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al listar Sucursales-Pack "+e.getMessage());
			return null;
		}
	}

	//-----------	METODOS PARA SUCURSAL-FRIO-CALOR----------------------------
	@Override
	public String insertSucursalFrioCalorVO(SucursalFrioCalorVO sucursalFrioCalor) {
		try {
			sucursalFrioCalorDao.insertSucursalFrioCalorVO(sucursalFrioCalor);
			return ConstantModel.SUCCESS;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al guardar un Sucrusal-FrioCalor "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String updateSucursalFrioCalorVO(SucursalFrioCalorVO sucursalFrioCalor) {
		try{
			sucursalFrioCalorDao.updateSucursalFrioCalorVO(sucursalFrioCalor);
			return ConstantModel.SUCCESS;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al Actualizar un SucursalFrioCalor "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String deleteSucursalFrioCalorVO(SucursalFrioCalorVO sucursalFrioCalor) {
		try{
			sucursalFrioCalorDao.deleteSucursalFrioCalorVO(sucursalFrioCalor);
			return ConstantModel.SUCCESS;
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al Eliminar un SucursalFrioCalor "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public SucursalFrioCalorVO getSucursalFrioCalorById(long sucursalFrioCalorId) {
		return null;
	}

	@Override
	public List<SucursalFrioCalorVO> getSucursalesFrioCalor() {
		try {
			return sucursalFrioCalorDao.getAllSucursalFrioCalorVO();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al listar Sucursales-FrioCalor "+e.getMessage());
			return null;
		}
	}

	@Override
	public List<SucursalFrioCalorVO> getSucursalFrioCalorBySucursal(SucursalVO sucursal) {
		try {
			return sucursalFrioCalorDao.getAllSucursalFrioCalorBySucursal(sucursal);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al listar Sucursales-FrioCalor por sucursal "+e.getMessage());
			return null;
		}
	}
	
	// --- ASIGNACIONES ----
	@Override
	public String assignProductosSucursal(SucursalVO s, DesProdTipoCliVO[] productosSeleccionados) {
		try {
			for(int i=0; i<productosSeleccionados.length;i++){
				if(!isAssigned(s, productosSeleccionados[i].getProducto())){
					SucursalProductoVO sp = new SucursalProductoVO();
					sp.setFechaAsignacion(new Date());
					sp.setProductoDescuento(productosSeleccionados[i]);
					sp.setSucursal(s);
					insertSucursalProductoVO(sp);	
				}
			}
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			System.out.println("Error al guardar los productos a la sucursal con ID: "+s.getSucursalId());
			return ConstantModel.FAILED;
		}
	}

	/**
	 * Verifica si un producto esta asignado a una sucursal.
	 * @param sucursal
	 * @param producto
	 * @return true si esta asignado.
	 */
	private boolean isAssigned(SucursalVO sucursal,ProductoVO p){
		boolean result = false;
		try {
			for(SucursalProductoVO sp: sucursalProductoDao.getAllSucursalProductoBySucursal(sucursal)){
				if(sp.getProductoDescuento().getProducto().equals(p)){
					return true;
				}
			}
			return false;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			result = false;
		}
		return result;
	}
	
	
	@Override
	public String modificarProductoSucursal(SucursalVO s,
			DesProdTipoCliVO[] productosSeleccionados) {
		try {
			List<SucursalProductoVO> productosAsignados = sucursalProductoDao.getAllSucursalProductoBySucursal(s);
			for(SucursalProductoVO sp: productosAsignados){
				if(!isInProductosSeleccionados(sp.getProductoDescuento().getProducto(), productosSeleccionados)){
					sucursalProductoDao.updateSucursalProductoVO(sp);
				}
			}
			assignProductosSucursal(s, productosSeleccionados);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return ConstantModel.FAILED;
		}
	}
	
	private boolean isInProductosSeleccionados(ProductoVO p, DesProdTipoCliVO[] productosSeleccionados){
		for(int i=0; i<productosSeleccionados.length;i++){
			if(p.equals(productosSeleccionados[i].getProducto())){
				return true;
			}
		}
		return false;
	}
	
	@Override
	public String assignEquiposSucursal(SucursalVO s, FrioCalorVO[] equiposSeleccionados) {
		
		for(int i=0; i< equiposSeleccionados.length;i++){
			
			SucursalFrioCalorVO sfc = new SucursalFrioCalorVO();
			
			sfc.setFechaAsignacion(new Date());
			sfc.setFrioCalor(equiposSeleccionados[i]);
			sfc.setSucursal(s);
			
			sfc.setCantidad(1);
			
			sfc.setTipoComercializacion("PACK");
			sfc.setComercializacionId((long)1);
//			sfc.setUbicacion("POR DEFECTO");
			sfc.setUbicacion(equiposSeleccionados[i].getUbicacion());
			
			
			insertSucursalFrioCalorVO(sfc);
			
		}
		return null;
	}
	
	@Override
	public String assignEquiposSucursal2(SucursalVO s,
			List<SucursalFrioCalorVO> equiposSeleccionados
			,String tipoComercializacion
			,long comercializacionId) {
		
		try {
			FrioCalorDao fcDao = new FrioCalorDaoImp();
			List<SucursalFrioCalorVO> equiposAsignados = sucursalFrioCalorDao.getAllSucursalFrioCalorBySucursal(s);
			for(SucursalFrioCalorVO sfc: equiposAsignados){
				if(estaEnLaNuevaAsignacion(equiposSeleccionados, sfc)){
					equiposSeleccionados.remove(sfc);
				}else {
					sucursalFrioCalorDao.deleteSucursalFrioCalorVO(sfc);
					
					//--- Lo dejamos disponible al frio calor
					FrioCalorVO fc = sfc.getFrioCalor();
					fc.setEstado(ConstantModel.ESTADO_FRIO_CALOR.FABRICA.getEstado());
					fcDao.updateFrioCalorVO(fc);
				}
			}
			if(equiposSeleccionados.size()>0){
				
				Date fechaAsignacion = new Date();
				for(SucursalFrioCalorVO sfc: equiposSeleccionados){				
					sfc.setSucursal(s);
					sfc.setCantidad(0);
					sfc.setComercializacionId(comercializacionId);
					sfc.setFechaAsignacion(fechaAsignacion);
					sfc.setTipoComercializacion(tipoComercializacion);
					sucursalFrioCalorDao.insertSucursalFrioCalorVO(sfc);
					
					FrioCalorVO fc = sfc.getFrioCalor();
					fc.setEstado(ConstantModel.ESTADO_FRIO_CALOR.CLIENTE.getEstado());
					fcDao.updateFrioCalorVO(fc);
				}
			}
			return ConstantModel.SUCCESS;
		}
		catch (Exception e) {
			e.printStackTrace();
			return ConstantModel.FAILED;
		}
	}

	private boolean estaEnLaNuevaAsignacion(List<SucursalFrioCalorVO> equiposNew, SucursalFrioCalorVO sucursalFrioCalor){
		for(SucursalFrioCalorVO sfc: equiposNew){
			if(sfc.getSucursalFrioCalorId() != null){
				if(sfc.getSucursalFrioCalorId().equals(sucursalFrioCalor.getSucursalFrioCalorId())){
					return true;
				}
			}
		}
		return false;
	}
	
	
	@Override
	public List<SucursalVO> getSucursalesByTipoSujeto(String tipoSujeto) {
		try{
			return sucursalDao.getAllSucursalesByTipoSujeto(tipoSujeto);
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("Error al listar Sucursales by tipo de sujeto "+e.getMessage());
			return null;
		}
	}

	@Override
	public List<SucursalVO> getSucursalesBySucursal(SucursalVO sucursal) {
		List<SucursalVO> result = new ArrayList<SucursalVO>();
		try {
			result = sucursalDao.getSucursalesBySucursal(sucursal);
			for(SucursalVO s: result){
				s.setDomicilioCompleto(Util.getDireccion(s));
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public List<ComercializacionMesVencidoVO> getProductosComercializadosAMesVencido(
			SucursalVO sucursal) {
		try {
			
			List<ComercializacionMesVencidoVO> result = comercializacionMesVencidoDao.getProductosComercializadosAMesVencido(sucursal);
			for(ComercializacionMesVencidoVO cmv : result){
				float precio = cmv.getDescuentoProducto().getProducto().getPrecio() - cmv.getDescuentoProducto().getProducto().getPrecio() * cmv.getDescuentoProducto().getPorcentajeDescuento()/100;
				cmv.getDescuentoProducto().getProducto().setPrecio(precio);
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public SucursalVO getSucursalBySujetoYNumeroSucursal(SujetoVO sujeto,
			Long numeroSucursal) {
		try {
			return sucursalDao.getSucursalVOBySujetoNumeroSucursal(sujeto, numeroSucursal);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		
	}

}
